﻿using DotNetty.Buffers;
using DotNetty.Codecs;
using DotNetty.Extensions;
using DotNetty.Transport.Channels;
using System.Net;
using System.Text;

var server = new TcpSocketServer(8000);

server.OnCreateBootstrap += bootstrap =>
{
    bootstrap.Option(ChannelOption.TcpNodelay, true);
};

server.OnChannelPipeline += pipeline =>
{
    //心跳
    //pipeline.AddLast(new IdleStateHandler(60, 0, 0));

    //编码解码器
    pipeline.AddLast(new LengthFieldPrepender(2));
    pipeline.AddLast(new LengthFieldBasedFrameDecoder(ushort.MaxValue, 0, 2, 0, 2));

    pipeline.AddLast(new MyStringDecoder());

    //tls证书
    //var cert = new X509Certificate2(Path.Combine(ExampleHelper.ProcessDirectory, "dotnetty.com.pfx"), "password");
    //pipeline.AddLast(TlsHandler.Server(cert));
};

server.OnStarting += () =>
{
    Console.WriteLine("Starting...");
};

server.OnStarted += () =>
{
    Console.WriteLine("Started.");
};

server.OnStopped += async ex =>
{
    Console.WriteLine($"Stopped==>{ex?.Message}");
    await Task.Delay(2000);
    await server.StartAsync(); //restart
};

server.OnClientConnected += cnn =>
{
    var addr = (IPEndPoint)cnn.Channel.RemoteAddress;

    Console.WriteLine($"ClientConnected==>{cnn.Id}==>IP:{addr.Address}==>Port:{addr.Port}");
    Console.WriteLine($"ClientCount：{server.ClientDict.Count}");
};

server.OnClientMessage += async (cnn, message) =>
{
    if (message is IByteBuffer buffer)
    {
        var txt = buffer.ToString(Encoding.UTF8);
        Console.WriteLine($"ClientMessage==>{cnn.Id}===>{txt}");
    }
    else if (message is string str)
    {
        Console.WriteLine($"ClientMessage==>{cnn.Id}===>{str}");
    }

    var txtSend = Encoding.UTF8.GetBytes("this is from tcp server message!");
    await cnn.WriteAndFlushAsync(txtSend);
};

server.OnClientException += (cnn, ex) =>
{
    Console.WriteLine($"ClientException==>{cnn.Id}==>{ex?.Message}");
};

server.OnClientDisconnected += cnn =>
{
    Console.WriteLine($"ClientDisconnected==>{cnn.Id}");
    Console.WriteLine($"ClientCount：{server.ClientDict.Count}");
};

await server.StartAsync();

Console.ReadKey();

await server.DisposeAsync();

Console.WriteLine("Hello, World!");


public class MyStringDecoder : MessageToMessageDecoder<IByteBuffer>
{
    protected override void Decode(IChannelHandlerContext ctx, IByteBuffer message, List<object> output)
    {
        // 直接将IByteBuffer转为字符串
        output.Add(message.ToString(Encoding.UTF8));
    }
}
